import matplotlib.pyplot as plt

from util.util_excel import read_csv


def calculate_accuracy(data):
    """
    计算预测值的正确率。

    :param data: 包含 CSV 数据的 DataFrame
    :return: 正确率
    """
    if data is None or data.empty:
        print("数据为空，无法计算正确率。")
        return None
    # 计算正确预测的样本数
    correct_predictions = (data['score'] == data['score_ai_final']).sum()
    total_samples = len(data)
    if total_samples == 0:
        print("总样本数为 0，无法计算正确率。")
        accuracy = 0
    else:
        accuracy = correct_predictions / total_samples
    return accuracy, correct_predictions, total_samples


def calculate_accuracy_target(data, score_value):
    accuracy, correct_predictions, total_samples = None, None, None
    if data is None or data.empty:
        print("数据为空，无法计算正确率。")
        return accuracy, correct_predictions, total_samples
    # 筛选出 score 为指定值的样本
    filtered_data = data[data['score'] == score_value]
    if filtered_data.empty:
        print(f"没有找到 score 为 {score_value} 的样本。")
        return accuracy, correct_predictions, total_samples
    # 计算正确预测的样本数
    correct_predictions = (filtered_data['score'] == filtered_data['score_ai_final']).sum()
    total_samples = len(filtered_data)
    if total_samples == 0:
        print("总样本数为 0，无法计算正确率。")
        accuracy = 0
    else:
        accuracy = correct_predictions / total_samples
    return accuracy, correct_predictions, total_samples


def plot_scores(data):
    """
    绘制 data['score'] 和 data['score_ai_final'] 的折线图。
    :param data: 包含 CSV 数据的 DataFrame
    """
    if data is None or data.empty:
        print("数据为空，无法绘制折线图。")
        return
    # 获取索引
    indices = range(len(data))
    # 创建一个新的图形
    plt.figure(figsize=(10, 5))  # 例如，宽度为10英寸，高度为5英寸
    plt.plot(indices, data['score'], label='Real Score', marker='o')
    plt.plot(indices, data['score_ai_final'], label='Predicted Score', marker='x')
    # 添加标题和标签
    plt.title('Comparison of Real and Predicted Scores')
    plt.xlabel('Sample Index')
    plt.ylabel('Score')
    plt.legend()
    # 显示网格
    plt.grid(True)
    # 显示图形
    plt.show()


# 计算每部分的精确得分
def main_accuracy_prec():
    # CSV 文件路径
    file_path = f"files/test_back_score5_v2.csv"
    # 读取 CSV 文件
    data = read_csv(file_path)
    if data is None:
        print("data is None!")
        return
    # 计算正确率
    accuracy, correct_predictions, total_samples = calculate_accuracy(data)
    # 输出结果
    print(f"Total samples: {total_samples}")
    print(f"Correct predictions: {correct_predictions}")
    print(f"Accuracy: {accuracy:.2%}")
    # 计算单部分正确率
    accuracy0, correct_predictions0, total_samples0 = calculate_accuracy_target(data, 0)
    if accuracy0 is not None:
        print("accuracy0=%f, correct_predictions0=%d, total_samples0=%d"
              % (accuracy0, correct_predictions0, total_samples0))
    else:
        print("score 0 not exist")
    accuracy1, correct_predictions1, total_samples1 = calculate_accuracy_target(data, 1)
    if accuracy1 is not None:
        print("accuracy1=%f, correct_predictions1=%d, total_samples1=%d"
              % (accuracy1, correct_predictions1, total_samples1))
    else:
        print("score 1 not exist")
    accuracy2, correct_predictions2, total_samples2 = calculate_accuracy_target(data, 2)
    if accuracy2 is not None:
        print("accuracy2=%f, correct_predictions2=%d, total_samples2=%d"
              % (accuracy2, correct_predictions2, total_samples2))
    else:
        print("score 2 not exist")
    accuracy3, correct_predictions3, total_samples3 = calculate_accuracy_target(data, 3)
    if accuracy3 is not None:
        print("accuracy3=%f, correct_predictions3=%d, total_samples3=%d"
              % (accuracy3, correct_predictions3, total_samples3))
    else:
        print("score 3 not exist")
    accuracy4, correct_predictions4, total_samples4 = calculate_accuracy_target(data, 4)
    if accuracy4 is not None:
        print("accuracy4=%f, correct_predictions4=%d, total_samples4=%d"
              % (accuracy4, correct_predictions4, total_samples4))
    else:
        print("score 4 not exist")
    accuracy5, correct_predictions5, total_samples5 = calculate_accuracy_target(data, 5)
    if accuracy5 is not None:
        print("accuracy5=%f, correct_predictions5=%d, total_samples5=%d"
              % (accuracy5, correct_predictions5, total_samples5))
    else:
        print("score 5 not exist")
    # 画样本折线图
    plot_scores(data)


# 计算上下限分数范围内正确率
def calculate_accuracy_range(datas, score_target, score_upper, score_lower):
    count_total = 0
    count_right = 0
    for data in datas.values:
        score_real = data[2]
        score_ai = data[8]
        if score_real == score_target:
            count_total += 1
            if score_ai >= score_lower and score_ai <= score_upper:
                count_right += 1
        #     print("score_real:", score_real, ", score_ai:", score_ai,
        #           ", count_total:", count_total, ", count_right:", count_right)
        # print("---------------------------------")
    return count_total, count_right


# 计算每部分的范围得分
def main_accuracy_range():
    # CSV 文件路径
    file_path = f"files/test_back_score5_v2.csv"
    # 读取 CSV 文件
    datas = read_csv(file_path)
    if datas is None:
        print("data is None!")
        return
    # 计算范围正确率
    count_total_0, count_right_0 = calculate_accuracy_range(datas, 0, 1, 0)
    count_total_1, count_right_1 = calculate_accuracy_range(datas, 1, 2, 0)
    count_total_2, count_right_2 = calculate_accuracy_range(datas, 2, 3, 1)
    count_total_3, count_right_3 = calculate_accuracy_range(datas, 3, 4, 2)
    count_total_4, count_right_4 = calculate_accuracy_range(datas, 4, 5, 3)
    count_total_5, count_right_5 = calculate_accuracy_range(datas, 5, 5, 4)
    if count_total_0 > 0:
        print("count_total_0:", count_total_0, ", count_right_0:", count_right_0,
              ", accuracy rate:", (count_right_0 * 100 / count_total_0), "%")
    if count_total_1 > 0:
        print("count_total_1:", count_total_1, ", count_right_1:", count_right_1,
              ", accuracy rate:", (count_right_1 * 100 / count_total_1), "%")
    if count_total_2 > 0:
        print("count_total_2:", count_total_2, ", count_right_2:", count_right_2,
              ", accuracy rate:", (count_right_2 * 100 / count_total_2), "%")
    if count_total_3 > 0:
        print("count_total_3:", count_total_3, ", count_right_3:", count_right_3,
              ", accuracy rate:", (count_right_3 * 100 / count_total_3), "%")
    if count_total_4 > 0:
        print("count_total_4:", count_total_4, ", count_right_4:", count_right_4,
              ", accuracy rate:", (count_right_4 * 100 / count_total_4), "%")
    if count_total_5 > 0:
        print("count_total_5:", count_total_5, ", count_right_5:", count_right_5,
              ", accuracy rate:", (count_right_5 * 100 / count_total_5), "%")





if __name__=="__main__":
    main_accuracy_prec()
    main_accuracy_range()